Amazon LexがCloudFormation対応したので、みんなが触るであろうお花を注文するやつを作ってみた
いわさです。
先日、CloudFormationでAmazon Lexがサポートされました。
Amazon Lexのチュートリアルでははじめにお花を注文するサンプルテンプレート"OrderFlowers"を使うかと思います。
本日はCloudFormationでOrderFlowersテンプレートを作成することでLexの各コンポーネントを理解してみたいと思います。
対応リソース
まず、作成出来るリソースはV2となります。
そして、対応しているリソースは以下4つです。
AWS::Lex::Bot
AWS::Lex::BotAlias
AWS::Lex::BotVersion
AWS::Lex::ResourcePolicy
リソースポリシーはLambdaと変わらないので、それ以外の3つを試してみたいと思います。
最小構成
まず、リソース作成をするためだけの最小テンプレートは以下となります。
※ロールは別途用意が必要です。
AWSTemplateFormatVersion: 2010-09-09 Description: Lex V2 Bot Template Parameters: BotName: Description: Bot Name. Type: String Resources: Bot: Type: AWS::Lex::Bot Properties: DataPrivacy: ChildDirected: false IdleSessionTTLInSeconds: 300 Name: !Ref BotName RoleArn: !GetAtt BotRuntimeRole.Arn
こちらを実行すると以下が作成されます。
Lexボットリソースのみを作成しますが、デフォルトバージョンのドラフト
とデフォルトエイリアスのTestBotAlias
は自動作成されます。
バージョンとエイリアスについては後述します。
一方で、ロケールやインテントは何も定義されていないので、ビルドも実行も出来ない状態です。
ボットの大枠が存在しているだけの状態です。
ロケール・言語、デフォルトインテントの作成
ボットでは、1つ以上の言語とロケールを作成しどの言語でユーザーと対話するかをまず選択する必要があります。
そして、対話を通して行うアクションであるインテントを定義します。
ここがボット定義のメイン部分になります。
インテントを作成した後にビルドすることで実行出来るようになりますが、ビルドするためには、デフォルトのフォールバックインテントとSample utterances
を持つカスタムインテントが1つ必要です。
Sample utterances
とは、ユーザーの発話例となり、この情報を使ってインテントが開始されます。
ここまでをまとめると、"ビルド・実行が可能"な最小テンプレートは以下となります。
Bot: Type: AWS::Lex::Bot Properties: DataPrivacy: ChildDirected: false IdleSessionTTLInSeconds: 300 Name: !Ref BotName RoleArn: !GetAtt BotRuntimeRole.Arn AutoBuildBotLocales: false BotLocales: - LocaleId: ja_JP NluConfidenceThreshold: 0.5 Intents: - Name: FallbackIntent ParentIntentSignature: "AMAZON.FallbackIntent" - Name: HogeIntent SampleUtterances: - Utterance: Fuga
ビルドしてテストしてみましょう。
最低限ユーザーと対話出来るリソースを用意することが出来ました。
この状態では、マネジメントコンソールで「空のボットを作成します。」を選択し、言語と発話を追加直後と同等の状態です。
インテントを実装する
ここからサンプルテンプレートのようにしっかりした対話を実装するためにはインテントを作り込む必要があります。
サンプルテンプレートのインテントを先に見てみましょう。
まず、発話例としてユーザーから花を注文したいという発話が定義されています。
そして、インテントにはスロット
という概念が仕組みがあります。
スロットはインテントの実行を行うためのパラメータを指しており、ボットがユーザーから対話形式で収集します。
また、確認プロンプトを使うことで、ボットがインテントを履行するかユーザーに確認することが出来ます。
ユーザーはそのタイミングでキャンセルすることも可能です。
サンプルではスロットに以下を定義しています。
- どの花か
- いつ受け取るか(何日、何時)
スロットには型があり、組み込みスロットタイプとカスタムスロットタイプの概念があります。
組み込みスロットタイプは事前にLexで定義されているものですぐに使用することが出来ます。
組み込みスロットタイプ - Amazon Lex
今回のサンプルでは受け取り日時は組み込みスロットタイプを使っており、花の種類はカスタムスロットタイプを使っています。
ここまでのサンプルボット相当をCloudFormationテンプレートで表現すると、以下のようになります。
Bot: Type: AWS::Lex::Bot Properties: DataPrivacy: ChildDirected: false IdleSessionTTLInSeconds: 300 Name: !Ref BotName RoleArn: !GetAtt BotRuntimeRole.Arn AutoBuildBotLocales: false BotLocales: - LocaleId: ja_JP NluConfidenceThreshold: 0.5 # カスタムスロットタイプ SlotTypes: - Name: FlowerTypes ValueSelectionSetting: ResolutionStrategy: ORIGINAL_VALUE SlotTypeValues: - SampleValue: Value: ユリ - SampleValue: Value: バラ - SampleValue: Value: チューリップ # インテント Intents: - Name: FallbackIntent Description: 花のブーケを注文するインテント ParentIntentSignature: AMAZON.FallbackIntent - Name: HogeIntent # サンプル発話 SampleUtterances: - Utterance: 花を注文 - Utterance: 花を注文します # スロット Slots: - Name: FlowerType SlotTypeName: FlowerTypes ValueElicitationSetting: SlotConstraint: Required PromptSpecification: MaxRetries: 3 MessageGroupsList: - Message: PlainTextMessage: Value: どのような花を注文しますか? - Name: PickupDate SlotTypeName: AMAZON.Date ValueElicitationSetting: SlotConstraint: Required PromptSpecification: MaxRetries: 3 MessageGroupsList: - Message: PlainTextMessage: Value: 何日に {FlowerType} を受け取りますか? - Name: PickupTime SlotTypeName: AMAZON.Time ValueElicitationSetting: SlotConstraint: Required PromptSpecification: MaxRetries: 3 MessageGroupsList: - Message: PlainTextMessage: Value: 何時に {FlowerType} を受け取りますか? # スロットの優先順位 SlotPriorities: - Priority: 1 SlotName: FlowerType - Priority: 2 SlotName: PickupDate - Priority: 3 SlotName: PickupTime # 確認プロンプトと応答拒否 IntentConfirmationSetting: PromptSpecification: MaxRetries: 3 MessageGroupsList: - Message: PlainTextMessage: Value: わかりました。{FlowerType} は {PickupDate} の {PickupTime} に受け取ることができます。これでよろしいですか? DeclinationResponse: MessageGroupsList: - Message: PlainTextMessage: Value: それでは、注文は行いません。
実行してみましょう。
良いですね。
バージョン
サンプルボットに関してはここまでとなります。
CloudFormationではバージョンの作成も行うことが出来ます。
Lexにはバージョンの概念があります。
ボットにはデフォルトの「ドラフト」バージョンが必ず存在しており、設定変更や開発はドラフトバージョンで行います。
そしてボットをデプロイする任意のタイミングでバージョンを作成します。
バージョンは読み取り専用のスナップショットです。
Creating versions - Amazon Lex
以下のテンプレートで作成することが出来ます。
BotVersion1: Type: AWS::Lex::BotVersion Properties: BotId: !Ref Bot BotVersionLocaleSpecification: - LocaleId: ja_JP BotVersionLocaleDetails: SourceBotVersion: DRAFT
バージョン番号はLexで管理されています。 よってCloudFormation上で上記リソースを削除してスタックを更新後に、再度同じリソースを作成した場合は新たなバージョンが作成されます。
エイリアス
エイリアスは特定バージョンを指すポインタです。
バージョンを直接参照する場合、ボットを利用する外部からはバージョンアップごとに参照コードや設定のアップデートが必要になってしまいます。
エイリアス参照させておくことで、エイリアスの更新のみで参照する実体を切り替えることが出来ます。DNSを使ったアップデートに似ていますね。
エイリアスは以下のような形でバージョン番号を指定して定義します。
BotVersion1: Type: AWS::Lex::BotVersion Properties: BotId: !Ref Bot BotVersionLocaleSpecification: - LocaleId: ja_JP BotVersionLocaleDetails: SourceBotVersion: DRAFT BotVersion2: Type: AWS::Lex::BotVersion Properties: BotId: !Ref Bot BotVersionLocaleSpecification: - LocaleId: ja_JP BotVersionLocaleDetails: SourceBotVersion: DRAFT BotProd: Type: AWS::Lex::BotAlias Properties: BotId: !Ref Bot BotAliasName: "Prod" BotVersion: !GetAtt BotVersion1.BotVersion BotBeta: Type: AWS::Lex::BotAlias Properties: BotId: !Ref Bot BotAliasName: "Beta" BotVersion: !GetAtt BotVersion2.BotVersion
この状態で新規バージョンを作成していっても、参照する外部システムは何の影響も受けません。
上記では安定版とベータ版という形でエイリアスを用意しましたが、エイリアスを以下のように更新することで、ベータ版のみバージョンアップさせることが出来ます。
BotVersion1: Type: AWS::Lex::BotVersion Properties: BotId: !Ref Bot BotVersionLocaleSpecification: - LocaleId: ja_JP BotVersionLocaleDetails: SourceBotVersion: DRAFT BotVersion2: Type: AWS::Lex::BotVersion Properties: BotId: !Ref Bot BotVersionLocaleSpecification: - LocaleId: ja_JP BotVersionLocaleDetails: SourceBotVersion: DRAFT BotVersion3: Type: AWS::Lex::BotVersion Properties: BotId: !Ref Bot BotVersionLocaleSpecification: - LocaleId: ja_JP BotVersionLocaleDetails: SourceBotVersion: DRAFT BotProd: Type: AWS::Lex::BotAlias Properties: BotId: !Ref Bot BotAliasName: "Prod" BotVersion: !GetAtt BotVersion1.BotVersion BotBeta: Type: AWS::Lex::BotAlias Properties: BotId: !Ref Bot BotAliasName: "Beta" BotVersion: !GetAtt BotVersion3.BotVersion
さいごに
本日は新たにサポートされたCloudFormationを使って構築することで、Lex構築の基本となるインテント、運用の基本となるバージョンとエイリアスについて確認しました。
他サービスのインフラストラクチャと同じレベルで管理出来るようになったのはありがたいですね。
試してみる前は、ボットをCloudFormationで管理するなんて結構複雑なテンプレートになるのではなんて思ってましたが、想定したよりだいぶシンプルな実装をすることが出来ました。
ボット作成だけでなくバージョンとエイリアスでリリースの運用管理まで操作出来るようになっているのが嬉しいですね。
この検証では1つのスタックで全てのリソースをまとめてしまいましたが、最低限バージョンだけはバージョンアップ毎にテンプレートが肥大化していくのでインテントやエイリアスとはスタックを分けたほうが良さそうですね。